﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.ComponentModel;
using System.Data.Common;
using System.Threading;
using System.Collections;
using System.Globalization;
using Lime49.UI;
using LockCrypt.Core;

namespace LockCrypt {
    /// <summary>
    /// Shows the status of a BackgroundWorker
    /// </summary>
    public partial class WinWorkerLog : Window {
        public static readonly DependencyProperty AutoCloseProperty = DependencyProperty.Register("AutoClose", typeof(bool), typeof(WinWorkerLog), new PropertyMetadata(false));
        /// <summary>
        /// Gets or sets whether the window should close automatically after transfer finishes.
        /// </summary>
        /// <value><c>true</c> if the window should close automatically after transfer finishes, otherwise <c>false</c>.</value>
        public bool AutoClose {
            get { return (bool)base.GetValue(AutoCloseProperty); }
            set { base.SetValue(AutoCloseProperty, value); }
        }

        /// <summary>
        /// Gets whether the worker completed successfully.
        /// </summary>
        /// <value><c>true</c> if the worker completed successfully; otherwise, <c>false</c>.</value>
        public bool Success { get { return success; } }

        private Style styError,
                      stySuccess, // every successful query
                      styStatus, // intermediate status messages
                      styOther;
        private BackgroundWorker worker;
        private bool success = false;

        /// <summary>
        /// Initializes a new <see cref="WinWorkerLog"/>.
        /// </summary>
        /// <param name="caption">The window caption.</param>
        /// <param name="worker">The worker to execute.</param>
        public WinWorkerLog(string caption, BackgroundWorker worker) {
            InitializeComponent();
            this.Title = caption;
            this.worker = worker;
            ILogProvider logger = new RichTextBoxLogger(rtbProgress);
            worker.ProgressChanged += (s, pce) => {
                if(pce.UserState is StatusMessage) {
                    logger.Log(pce.UserState as StatusMessage);
                } else {
                    logger.Log(pce.UserState.ToString(), StatusMessage.StatusMessageType.Status);
                }
            };
            worker.RunWorkerCompleted += (s, rwe) => {
                if(rwe.Error != null) {
                    DialogBox.ShowAlert(this, rwe.Error.Message, "Error");
                } else {
                    this.success = true;
                }
                prgStatus.Visibility = Visibility.Hidden;
                btnClose.Visibility = Visibility.Visible;
                txtProgress.Focus();
                CommandManager.InvalidateRequerySuggested();
                if(AutoClose) {
                    DialogResult = success;
                }
            };
            styError = this.FindResource("ErrorStyle") as Style;
            stySuccess = this.FindResource("SuccessStyle") as Style;
            styStatus = this.FindResource("StatusStyle") as Style;
            styOther = this.FindResource("OtherStyle") as Style;
        }

        /// <summary>
        /// Begins translation when the window has finished loading.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param>
        private void Window_Loaded(object sender, RoutedEventArgs e) {
            txtProgress.Inlines.Clear();
            prgStatus.Visibility = Visibility.Visible;
            btnClose.Visibility = Visibility.Collapsed;
            worker.RunWorkerAsync();
        }

        /// <summary>
        /// Closes the window.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.Windows.Input.ExecutedRoutedEventArgs"/> instance containing the event data.</param>
        private void CloseWindow(object sender, ExecutedRoutedEventArgs e) {
            Close();
        }
    }
}
